/*
 * @(#) DateUtil.java 2011-4-21
 *
 * Copyright (c) 2010, Strong Technology. All Rights Reserved.
 * Strong Technology. CONFIDENTIAL
 */
package cn.strong.gweva.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;

/**
 * 日期处理类
 * 
 * @author lilanfei
 * @version 1.0
 * @since 2011-4-21
 */
public class DateUtil
{
	public static final int ONE_SECOND = 1000;
	public static final int ONE_MINUTE = 60 * ONE_SECOND;
	public static final int ONE_HOUR = 60 * ONE_MINUTE;
	public static final long ONE_DAY = 24 * ONE_HOUR;
	public static final long ONE_WEEK = 7 * ONE_DAY;
	/**
	 * @see TimeZone#getRawOffset
	 */
	@SuppressWarnings("unused")
	private static final int offSet;

	public static final String DATE_PATTERN_01 = "yyyy/MM/dd";
	public static final String DATE_PATTERN_02 = "yyyyMMddHHmmssSSS";
	public static final String DATE_PATTERN_03 = "yyyyMMddHHmmss";
	public static final String DATE_PATTERN_04 = "yyyy/MM/dd HH:mm:ss";
	public static final String DATE_PATTERN_05 = "HH:mm:ss";
	public static final String DATE_PATTERN_06 = "HH:mm";
	public static final String DATE_PATTERN_07 = "HHmm";
	public static final String DATE_PATTERN_08 = "yyyy/MM";
	public static final String DATE_PATTERN_09 = "yyyyMM";
	public static final String DATE_PATTERN_10 = "yyyy";
	public static final String DATE_PATTERN_11 = "MM";
	public static final String DATE_PATTERN_12 = "dd";
	public static final String DATE_PATTERN_13 = "MM/dd";
	public static final String DATE_PATTERN_14 = "yyyy/MM/dd HH:mm";
	public static final String DATE_PATTERN_15 = "yyyy-MM-dd";
	public static final String DATE_PATTERN_16 = "yyyyMMdd";
	public static final String DATE_PATTERN_17 = "yyyy-MM-dd HH:mm";
	public static final String DATE_PATTERN_18 = "yyyy-MM-dd HH:mm:ss";
	
	private static Set<String> datePatternSet;

	static
	{
		datePatternSet = new HashSet<String>();
		datePatternSet.add(DATE_PATTERN_01);
		datePatternSet.add(DATE_PATTERN_02);
		datePatternSet.add(DATE_PATTERN_03);
		datePatternSet.add(DATE_PATTERN_04);
		datePatternSet.add(DATE_PATTERN_05);
		datePatternSet.add(DATE_PATTERN_06);
		datePatternSet.add(DATE_PATTERN_07);
		datePatternSet.add(DATE_PATTERN_08);
		datePatternSet.add(DATE_PATTERN_09);
		datePatternSet.add(DATE_PATTERN_10);
		datePatternSet.add(DATE_PATTERN_11);
		datePatternSet.add(DATE_PATTERN_12);
		datePatternSet.add(DATE_PATTERN_13);
		datePatternSet.add(DATE_PATTERN_14);
		datePatternSet.add(DATE_PATTERN_15);
		datePatternSet.add(DATE_PATTERN_16);
		datePatternSet.add(DATE_PATTERN_17);
		datePatternSet.add(DATE_PATTERN_18);
		TimeZone timeZone = TimeZone.getDefault();
		offSet = timeZone.getRawOffset();
	}
	
	public static String formatDate(Date argDate, String argFormat) {
		if (argDate == null) {
			return "";
		}
		SimpleDateFormat sdfFrom = null;
		String strResult = null;

		try {
			sdfFrom = new SimpleDateFormat(argFormat);
			strResult = sdfFrom.format(argDate).toString();
		} catch (Exception e) {
			strResult = "";
		} finally {
			sdfFrom = null;
		}

		return strResult;
	}
	
	/**
	 * 根据日期取得日期的String
	 * @param pDate
	 * @param datePattern
	 * @return
	 */
	public static String getDateString(Date pDate, String datePattern)
	{
		if (StringUtil.isEmpty(datePattern) || !datePatternSet.contains(datePattern))
		{
			// throw new IllegalArgumentException("Date Pattern error!");
			return "";
		}

		if (pDate == null)
		{
			// throw new IllegalArgumentException("inputed Date error!");
			return "";
		}

		SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);

		return dateFormat.format(pDate);
	}

	/**
	 * String to date
	 * 
	 * @author 7308905
	 */
	public static Date getDateByString(String str, String datePattern)
	{
		if (StringUtil.isEmpty(datePattern) || !datePatternSet.contains(datePattern))
		{
			return null;
		}

		if (StringUtil.isEmpty(str))
		{
			return null;
		}

		SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);

		try
		{
			return dateFormat.parse(str);
		}
		catch (ParseException pe)
		{
			pe.printStackTrace();
		}

		return null;
	}

	/**
	 * 取得日期的星期（星期三）
	 * @param date
	 * @return
	 */
	static public String getXinqi(Date date)
	{
		String youbi = "";

		if (date == null)
		{
			return youbi;
		}

		SimpleDateFormat formatter = new SimpleDateFormat("E");
		youbi = formatter.format(date);

		return youbi;
	}
	
	/**
	 * 取得日期的星期，
	 * 星期一：1
	 * 星期二：2
	 * 星期三：3
	 * 星期四：4
	 * 星期五：5
	 * 星期六：6
	 * 星期日：7
	 * @param date
	 * @return
	 */
	public static int getXinqiInt(Date date)
	{
		int theWeek = 0;

		if (date == null)
		{
			return theWeek;
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		theWeek = calendar.get(Calendar.DAY_OF_WEEK);
		if (theWeek != 1)
		{
			theWeek = theWeek -1;
		}
		else
		{
			theWeek = 7;
		}
		return theWeek;
	}

	/**
	 * 取得系统时间
	 * 
	 * @return 系统时间
	 */
	public static Date getSysDate()
	{
		return new Date(System.currentTimeMillis());
	}
	
	/**
	 * 取得系统时间YYYYMMDD格式
	 * 
	 * @return 系统时间
	 */
	public static Date getSysDateYYYYMMDD()
	{
		Date today = getSysDate();
		String strToday = dt2Str(today);
		today = str2Dt(strToday);
		return today;
	}
	
	/**
	 * 
	 * @return
	 */
	public static Date getDateNoTime(Date dt)
	{
//		String strToday = dt2Str(dt);
//		Date newDt = str2Dt(strToday);
//		return newDt;
		if (dt == null) {
			return null;
		}
		Calendar cl = Calendar.getInstance();
		cl.setTimeInMillis(dt.getTime());
		cl.set(Calendar.HOUR_OF_DAY, 0);
		cl.set(Calendar.MINUTE, 0);
		cl.set(Calendar.SECOND, 0);
		cl.set(Calendar.MILLISECOND, 0);
		return cl.getTime();
	}

	/**
	 * 取得yyyyMMddHHmmssSSS格式的日期字符串
	 * 
	 * @param dt 日期
	 * @return 日期字符串
	 */
	public static String dateTime2Str(Date dt)
	{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
		return sdf.format(dt);
	}

	/**
	 * 取得yyyy/MM/dd格式的日期字符串
	 * 
	 * @param dt 日期
	 * @return 日期字符串(yyyy/MM/dd)
	 */
	public static String dt2Str(Date dt)
	{
		if (dt != null)
		{
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
			return sdf.format(dt);
		}
		else
		{
			return null;
		}
	}

	/**
	 * 通过yyyy/MM/dd格式的日期字符串，取得日期
	 * 
	 * @param ymd 日期字符串
	 * @return 日期
	 */
	public static Date str2Dt(String ymd)
	{
		if (ymd == null)
		{
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		try
		{
			Date ret = sdf.parse(ymd);
			return ret;
		}
		catch (ParseException e)
		{
			return null;
		}
	}

	/**
	 * 取得yyyyMMdd格式的日期字符串
	 * 
	 * @param dt 日期
	 * @return 日期字符串(yyyyMMdd)
	 */
	public static String dt2Str8(Date dt)
	{
		if (dt != null)
		{
			SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
			return sdf.format(dt);
		}
		else
		{
			return null;
		}
	}

	/**
	 * 取得HH:mm格式的日期字符串
	 * 
	 * @param dt 日期
	 * @return 日期字符串(HH:mm)
	 */
	public static String dt2HHmm(Date dt)
	{
		if (dt != null)
		{
			String date = dateTime2Str(dt);
			return date.substring(8, 10) + ":" + date.substring(10, 12);
		}
		else
		{
			return null;
		}

	}

	/**
	 * (HHmm) to (HH:mm)
	 */
	public static String dt2HHmm(String dt)
	{
		if (dt != null)
		{
			return dt.substring(0, 2) + ":" + dt.substring(2, 4);
		}
		else
		{
			return null;
		}

	}

	/**
     * 
     */
	public static Date add(Date date, int field, int amount)
	{
		if (date == null)
		{
			return null;
		}

		Calendar calendar = GregorianCalendar.getInstance(Locale.CHINA);
		calendar.setTime(date);
		calendar.add(field, amount);

		return calendar.getTime();
	}

	/**
     * 加N个月 
     */
	public static Date addMonths(Date date, int monthAmount)
	{
		return add(date, Calendar.MONTH, monthAmount);
	}

	/**
     * 加N天
     */
	public static Date addDays(Date date, int dayAmount)
	{
		return add(date, Calendar.DATE, dayAmount);
	}

	/**
     * 加N个小时
     */
	public static Date addHours24(Date date, int hourAmount)
	{
		return add(date, Calendar.HOUR_OF_DAY, hourAmount);
	}

	/**
     * 加N秒
     */
	public static Date addSeconds(Date date, int secondAmount)
	{
		return add(date, Calendar.SECOND, secondAmount);
	}

	/**
	 * 两个日期是否在一个月内
	 * @param dateFrom 开始时间
	 * @param dateTo 结束时间
	 * @param monthAmount
	 * @return
	 */
	public static boolean isScopeOfMonth(Date dateFrom, Date dateTo, int monthAmount)
	{
		if (!dateTo.before(DateUtil.addMonths(dateFrom, monthAmount)))
		{
			return false;
		}
		return true;
	}

	/**
	 * 获取时间（YYYY年MM月DD日 星期XX)
	 * 
	 * @return
	 */
	public static String getSysDateWeek()
	{
		int theYear = 0;
		int theMonth = 0;
		int theDay = 0;
		int theWeek = 0;
		String theWeekUpper = "";
		String thedate = "";

		Calendar calendar = Calendar.getInstance();

		theYear = calendar.get(Calendar.YEAR);
		theMonth = calendar.get(Calendar.MONTH) + 1;
		theDay = calendar.get(Calendar.DAY_OF_MONTH);
		theWeek = calendar.get(Calendar.DAY_OF_WEEK);

		switch (theWeek)
		{
			case 1:
				theWeekUpper = "日";
				break;
			case 2:
				theWeekUpper = "一";
				break;
			case 3:
				theWeekUpper = "二";
				break;
			case 4:
				theWeekUpper = "三";
				break;
			case 5:
				theWeekUpper = "四";
				break;
			case 6:
				theWeekUpper = "五";
				break;
			case 7:
				theWeekUpper = "六";
				break;
			default:
				break;
		}

		thedate = "" + theYear + "年" + theMonth + "月" + theDay + "日" + " 星期" + theWeekUpper;

		return thedate;
	}
	
	/**
	 * 日期显示
	 * @param b
	 * @return
	 */
	public static String getDateWeek(Date b)
	{
//		int theYear = 0;
		int theMonth = 0;
		int theDay = 0;
		int theWeek = 0;
		String theWeekUpper = "";
		String thedate = "";

		Calendar calendar = Calendar.getInstance();
		calendar.setTime(b);

//		theYear = calendar.get(Calendar.YEAR);
		theMonth = calendar.get(Calendar.MONTH) + 1;
		String strMonth = StringUtil.addZero(String.valueOf(theMonth), 2);
		theDay = calendar.get(Calendar.DAY_OF_MONTH);
		String strDay = StringUtil.addZero(String.valueOf(theDay), 2);
		theWeek = calendar.get(Calendar.DAY_OF_WEEK);

		switch (theWeek)
		{
			case Calendar.SUNDAY:
				theWeekUpper = "日";
				break;
			case Calendar.MONDAY:
				theWeekUpper = "一";
				break;
			case Calendar.TUESDAY:
				theWeekUpper = "二";
				break;
			case Calendar.WEDNESDAY:
				theWeekUpper = "三";
				break;
			case Calendar.THURSDAY:
				theWeekUpper = "四";
				break;
			case Calendar.FRIDAY:
				theWeekUpper = "五";
				break;
			case Calendar.SATURDAY:
				theWeekUpper = "六";
				break;
			default:
				break;
		}

		thedate = strMonth + "月" + strDay + "日(周" + theWeekUpper+")";

		return thedate;
	}
	
	public static Date mondayOfWeek(Date date) {
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		int dayOfWeek = cl.get(Calendar.DAY_OF_WEEK);
		dayOfWeek = dayOfWeek == 1 ? 6 : dayOfWeek - 2;
		cl.add(Calendar.DAY_OF_WEEK, -dayOfWeek);
		return cl.getTime();
	}

	public static Date sundayOfWeek(Date date) {
		Calendar cl = Calendar.getInstance();
		cl.setTime(date);
		int dayOfWeek = cl.get(Calendar.DAY_OF_WEEK);
		dayOfWeek = dayOfWeek == 1 ? 7 : dayOfWeek - 1;
		cl.add(Calendar.DAY_OF_WEEK, 7 - dayOfWeek);
		return cl.getTime();
	}
	
	/**
	 * 计算时间差
	 * @param fromDate 开始时间
	 * @param toDate	结束时间
	 * @return	相差几天
	 */
	public static int datePoor(Date fromDate, Date toDate)
	{
		
		return (int)((toDate.getTime() - fromDate.getTime())/(1000*60*60*24));
	}
	
	/**
	 * 找到最近的周一
	 * 
	 * @param k
	 * @return
	 */
	public static java.util.Date getNearMonday(java.util.Date k)
	{
		if (k != null)
		{
			return addDays(k, 0 - (getXinqiInt(k) - 1));
		}
		else
		{
			return null;
		}
	}
}
